import {Component, ComponentProps, VueComponent, Link, Hook, Mut, Computed} from "vue3-oop";
import {NButtonGroup, NButton, NDropdown, DropdownOption, NSpace} from "naive-ui";
import { nicon } from "@/utils/IconUtil";
import styles from "./index.module.scss";
import BpmnModeler from '../BpmnModeler';
import { MiniMap } from "@antv/x6-plugin-minimap";
import { Cell } from "@antv/x6";
import { BpmnElements,BpmnShapeNames } from '../BpmnModeler/elements'

interface IProps {
  bpmnModeler: BpmnModeler
}
@Component()
export default class ShapePanel extends VueComponent<IProps> {
  static defaultProps: ComponentProps<IProps> = {
    bpmnModeler:{},
  }

  constructor() {
    super()
  }

  @Mut() private state = {
    scale: 100,
    selectable: false,
    flowadjust: false,
    showMiniMap: false,
    contextX: 0,
    contextY: 0,
    contextShow: false,
    contextCell: undefined as undefined|Cell,
    contextOptions: [] as DropdownOption[],
  }

  private options = [
    {
      key: BpmnElements.CommitNode,
      label: BpmnShapeNames.CommitNode
    },{
      key: BpmnElements.UserNode,
      label: BpmnShapeNames.UserNode
    },{
      key: BpmnElements.ServiceNode,
      label: BpmnShapeNames.ServiceNode
    },{
      key: BpmnElements.GatewayNode,
      label: BpmnShapeNames.GatewayNode
    },{
      key: BpmnElements.FinishNode,
      label: BpmnShapeNames.FinishNode
    }
  ]

  private handleDragItem = (key: string,e:MouseEvent)=>{
    if((BpmnElements as any)[key]){
      const node = this.props.bpmnModeler.getGraph().createNode({shape: key});
      this.props.bpmnModeler.getDnd().start(node, e);
    }
  }

  private toggleSelectable=()=>{
    if(this.state.selectable){
      this.state.selectable = false;
      this.props.bpmnModeler.getGraph().unlockScroller();
      this.props.bpmnModeler.getGraph().enablePanning();
      this.props.bpmnModeler.getGraph().disableRubberband();
      // this.props.bpmnModeler.getGraph().disableSelection();
    }else{
      this.state.selectable = true;
      this.props.bpmnModeler.getGraph().lockScroller();
      this.props.bpmnModeler.getGraph().disablePanning();
      this.props.bpmnModeler.getGraph().enableRubberband();
      // this.props.bpmnModeler.getGraph().enableSelection();
    }
    // console.log(this.props.bpmnModeler.getGraph().isSelectionEnabled());
    // console.log(this.props.bpmnModeler.getGraph())
  }

  private toggleFlowAdjust=()=>{
    if(this.state.flowadjust){
      this.state.flowadjust = false;
      this.props.bpmnModeler.getGraph().getEdges().forEach((edge)=>{
        edge.removeTools(['vertices','segments','target-arrowhead']);
      });
    }else{
      this.state.flowadjust = true;
      this.props.bpmnModeler.getGraph().getEdges().forEach((edge)=>{
        edge.addTools(['vertices','segments','target-arrowhead']);
      });
    }
  }

  private handleNodeProps =(option: any)=>{
    option.props = option.props || {};
    option.props.style = option.props.style || {};
    option.props.style.userSelect = 'none';
    option.props.style.cursor = 'grab';
    option.props.onMousedown = (e:MouseEvent)=>{this.handleDragItem(option.key,e)}
    return option
  }

  

  private toggleMiniMap=()=>{
    this.state.showMiniMap = !this.state.showMiniMap;
  }

  /** 放大/缩小/重置 */
  private handleZoom=(value:number)=>{
    if(value===0){
      if(this.props.bpmnModeler.getGraph().getCellCount()===0){
        this.props.bpmnModeler.getGraph().center();
      }else{
        this.props.bpmnModeler.getGraph().zoomToFit({ maxScale: 1 });
        this.props.bpmnModeler.getGraph().center();
      }
    }else{
      this.props.bpmnModeler.getGraph().zoom(value/100);
    }
  }

  private handleUndo=()=>{
    this.props.bpmnModeler.getGraph().undo();
  }

  private handleRedo=()=>{
    this.props.bpmnModeler.getGraph().redo();
  }

  private handleClear=()=>{
    this.props.bpmnModeler.clearCells();
  }

  @Hook('Mounted')
  onMounted(){
    // 绑定小地图
    const miniMap = new MiniMap({
      container: document.querySelector(`.${styles.bpmn_shape_panel_minimap}`) as HTMLElement,
      width: 300, height: 200, padding:5, graphOptions:{ connecting: { router: 'orth'}}
    });
    this.props.bpmnModeler.getGraph().use(miniMap);
    // 监听放大缩小
    this.props.bpmnModeler.getGraph().on("scale", ({ sx, sy, ox, oy }) => {
      this.state.scale = Math.round(sx*100);
    });
    // 监听右键菜单
    this.props.bpmnModeler.getGraph().on("cell:contextmenu",this.openCellMenu);
  }

  // 打开节点、流转路径右键菜单
  private openCellMenu = ({ e, x, y, cell, view }:{e:MouseEvent,x:number,y:number,cell:Cell,view:any})=>{
    const contextOptions = [] as DropdownOption[];

    if(cell.shape!==BpmnElements.CommitNode&&cell.shape!==BpmnElements.FinishNode){
      contextOptions.push({
        label: '删除',
        key: 'DELETE',
        props: {
          onClick: ()=>{this.contextDeleteCell(cell);this.closeCellMenu();}
        }
      });
    }

    contextOptions.length>0 && setTimeout(()=>{
      this.state.contextCell = cell;
      this.state.contextOptions = contextOptions;
      this.state.contextX = e.clientX;
      this.state.contextY = e.clientY;
      this.state.contextShow = true;
    },this.state.contextShow?300:0);
  }

  // 关闭右键菜单
  private closeCellMenu = ()=>{
    this.state.contextCell = undefined;
    this.state.contextOptions = [];
    this.state.contextX = 0;
    this.state.contextY = 0;
    this.state.contextShow = false;
  }

  // 删除节点、流转路径
  private contextDeleteCell = (cell:Cell)=>{
    this.props.bpmnModeler.getGraph().removeCell(cell.id);
  }

  render(){
    const selectProps = !this.state.selectable?{}:{ghost:true,type:"info",style:{fontWeight:'bolder'}} as any;
    const flowProps = !this.state.flowadjust?{}:{ghost:true,type:"info",style:{fontWeight:'bolder'}} as any;
    const minimapProps = !this.state.showMiniMap?{}:{ghost:true,type:"info",style:{fontWeight:'bolder'}} as any;
    return(
      <>
        <NSpace class={[styles.bpmn_shape_panel]}>
          {/* <NButtonGroup size="small">
            <NButton onClick={()=>{}}>{{icon:nicon("AlignHorizontalLeftRound")}}</NButton>
            <NButton onClick={()=>{}}>{{icon:nicon("AlignHorizontalRightRound")}}</NButton>
            <NButton onClick={()=>{}}>{{icon:nicon("AlignVerticalTopRound")}}</NButton>
            <NButton onClick={()=>{}}>{{icon:nicon("AlignVerticalBottomRound")}}</NButton>
            <NButton onClick={()=>{}}>{{icon:nicon("AlignHorizontalCenterRound")}}</NButton>
            <NButton onClick={()=>{}}>{{icon:nicon("AlignVerticalCenterRound")}}</NButton>
          </NButtonGroup> */}
          <NButtonGroup size={"small"}>
            <NButton onClick={this.handleUndo}>{{icon:nicon("ArrowUndoSharp")}}</NButton>
            <NButton onClick={this.handleRedo}>{{icon:nicon("ArrowRedoSharp")}}</NButton>
            <NButton onClick={this.handleClear}>{{icon:nicon("MdRefreshCircle")}}</NButton>
          </NButtonGroup>
          <NButtonGroup size={"small"}>
            <NButton onClick={()=>{this.handleZoom(-5)}}>{{icon:nicon("ZoomOutOutlined")}}</NButton>
            <NButton onClick={()=>{this.handleZoom(0)}}>{`${this.state.scale}%`}</NButton>
            <NButton onClick={()=>{this.handleZoom(5)}}>{{icon:nicon("ZoomInOutlined")}}</NButton>
            <NButton {...minimapProps} onClick={this.toggleMiniMap}>{{icon:nicon("MapMarkedAlt")}}</NButton>
          </NButtonGroup>
          <NButtonGroup size="small">
            <NButton {...selectProps} onClick={this.toggleSelectable}>{{icon:nicon("Select02"),default:()=>"选取"}}</NButton>
            <NButton {...flowProps} onClick={this.toggleFlowAdjust}>{{icon:nicon("ArrowRouting20Filled"),default:()=>"路径"}}</NButton>
            <NDropdown
              size="small"
              options={this.options}
              nodeProps={this.handleNodeProps}
            >
              <NButton>{{icon:nicon("CropSquareOutlined"),default:()=>"添加节点"}}</NButton>
            </NDropdown>
          </NButtonGroup>
        </NSpace>
        {/* 小地图 */}
        <div class={[styles.bpmn_shape_panel_minimap]} style={{display:this.state.showMiniMap?'block':'none'}}></div>
        {/* 右键上下文菜单 */}
        <NDropdown 
          placement="bottom-start" 
          size="small"
          trigger="manual" 
          x={this.state.contextX} 
          y={this.state.contextY} 
          show={this.state.contextShow}
          options={this.state.contextOptions} 
          onClickoutside={this.closeCellMenu}
        />
      </>
    )
  }
}